package com.ruifu.bom.controller;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.api.R;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fhzncloud.cloud.common.security.service.CloudUser;
import com.fhzncloud.cloud.common.security.util.SecurityUtils;
import com.ruifu.bom.dto.MaterielTypeDTO;
import com.ruifu.bom.service.MaterielTypeService;
import com.ruifu.bom.vo.MaterielAndVersionsVO;
import com.ruifu.bom.vo.MaterielTypeVO;
import com.ruifu.common.eneity.BaseEntityPlus;
import com.ruifu.common.po.MaterielType;
import com.ruifu.common.utils.BeanConverter;
import com.ruifu.common.utils.StrUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 物料分类控制层
 *
 * @author nyr
 * @create 2019/12/23
 */
@RestController
@CrossOrigin
@RequestMapping("/materielType")
@Api(tags = "物料类型相关接口", description = "提供物料类型相关的 Rest API")
public class MaterielTypeController {
    @Autowired
    private MaterielTypeService materielTypeService;
    /**
     * 用于存储登陆人信息
     */
    private CloudUser cloudUser;

    /**
     * 通过url请求方法之前,调用该方法获取登陆人信息
     */
    @ModelAttribute
    public void before() {
        cloudUser = SecurityUtils.getUser();
    }

    /**
     * 联合查询
     *
     * @param current
     * @param size
     * @param materielTypeDTO
     * @return
     */
    @PostMapping("/page/{current}/{size}")
    public Page<MaterielType> page(@PathVariable long current, @PathVariable long size,
                                   @RequestBody MaterielTypeDTO materielTypeDTO) {
        try {
            return materielTypeService.findByPage(new Page<>(current, size), materielTypeDTO, cloudUser);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    @GetMapping("/findById/{mtId}")
    @ApiOperation("根据分类id查询分类详情")
    @ApiImplicitParam(name = "mtId", value = "物料分类id", dataType = "Long")
    public R findById(@PathVariable Long mtId) {
        try {
            return R.ok(materielTypeService.getById(mtId));
        } catch (Exception e) {
            e.printStackTrace();
            return R.failed(e.getMessage());
        }
    }

    /**
     * 校验物料分类代号是否可用
     *
     * @param mtCode 物料分类代号
     * @return
     */
    @GetMapping("/checkoutByMtCode/{mtCode}")
    @ApiOperation("校验物料分类代号是否可用")
    @ApiImplicitParam(name = "mtCode", value = "物料分类代号", dataType = "String")
    public R checkoutByMtCode(@PathVariable String mtCode) {
        try {
            //根据物料分类代号和账套id查询物料分类代号是否存在
            int count = materielTypeService.count(Wrappers.<MaterielType>lambdaQuery()
                    .eq(MaterielType::getMtCode, mtCode)
                    .eq(BaseEntityPlus::getSetSid, SecurityUtils.getUser().getTenantId()));
            if (count != 0) {
                return R.failed("物料分类代号已存在");
            }
            return R.ok("物料分类代号可用");
        } catch (Exception e) {
            e.printStackTrace();
            return R.failed(e.getMessage());
        }
    }

    /**
     * 校验物料分类名称在同级中是否重复
     *
     * @param mtFatherId  物料分类父id
     * @param mtClassName 物料分类代号
     * @return
     */
    @GetMapping("/checkoutByMtClassName/{mtFatherId}/{mtClassName}")
    @ApiOperation("校验物料分类名称在同级中是否重复")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "mtFatherId", value = "物料分类父id", dataType = "string"),
            @ApiImplicitParam(name = "mtClassName", value = "物料分类代号", dataType = "string"),
    })
    public R checkoutByMtClassName(@PathVariable String mtFatherId,
                                   @PathVariable String mtClassName) {
        try {
            int count = materielTypeService.count(Wrappers.<MaterielType>lambdaQuery()
                    .eq(MaterielType::getMtFatherId, mtFatherId)
                    .eq(MaterielType::getMtClassName, mtClassName)
                    .eq(BaseEntityPlus::getSetSid, SecurityUtils.getUser().getTenantId()));
            if (count != 0) {
                return R.failed("当前物料分类下已存在名称[" + mtClassName + "]的分类");
            }
            return R.ok("物料分类名称可用");
        } catch (Exception e) {
            e.printStackTrace();
            return R.failed(e.getMessage());
        }
    }

    /**
     * 新增物料分类
     *
     * @param materielTypeDTO 物料分类传输对象
     * @return
     */
    @PostMapping("/save")
    @ApiOperation("新增物料分类")
    public R save(@RequestBody MaterielTypeDTO materielTypeDTO) {
        try {
            //物料扩展属性集合定义大小写转换(,  ;)
            materielTypeDTO.setMtExtendAttribute(StrUtils.upperToLower(materielTypeDTO.getMtExtendAttribute()));
            return R.ok(materielTypeService.save(materielTypeDTO));
        } catch (Exception e) {
            e.printStackTrace();
            return R.failed(e.getMessage());
        }
    }

    /**
     * 删除类型
     *
     * @param mtIds 物料分类id
     * @return
     */
    @DeleteMapping("/delete")
    @ApiOperation("删除类型")
    public R delete(@RequestBody List<Long> mtIds) {
        try {
            for (Long mtId : mtIds) {
                //校验该类型是否被引用
                Integer count = materielTypeService.getBaseMapper().selectCount(Wrappers.<MaterielType>lambdaQuery()
                        .eq(MaterielType::getMtFatherId, mtId)
                        .eq(BaseEntityPlus::getSetSid, SecurityUtils.getUser().getTenantId()));
                MaterielType materielType = materielTypeService.getById(mtId);
                if (count != 0) {
                    return R.failed("类型名称为：" + materielType.getMtClassName() + " 的类型被引用,无法被删除");
                }
                return R.ok(materielTypeService.removeById(mtId));
            }
        } catch (Exception e) {
            return R.failed(e.getMessage());
        }
        return null;
    }

    /**
     * 删除物料分类
     *
     * @param mtId 物料分类id
     * @return
     */
    @DeleteMapping("/deleteById/{mtId}")
    @ApiOperation("删除物料分类")
    @ApiImplicitParam(name = "mtId", value = "物料分类id", dataType = "Long")
    public R deleteById(@PathVariable Long mtId) {
        try {
            return materielTypeService.deleteById(mtId);
        } catch (Exception e) {
            e.printStackTrace();
            return R.failed(e.getMessage());
        }
    }

    /**
     * 修改物料分类
     *
     * @param materielTypeDTO 物料分类传输对象
     * @return
     */
    @PostMapping("/update")
    @ApiOperation("修改物料分类")
    public R update(@RequestBody MaterielTypeDTO materielTypeDTO) {
        try {
            //根据物料分类id修改物料分类
            materielTypeDTO.setMtExtendAttribute(StrUtils.upperToLower(materielTypeDTO.getMtExtendAttribute()));
            return R.ok(materielTypeService.updateById(materielTypeDTO));
        } catch (Exception e) {
            e.printStackTrace();
            return R.failed(e.getMessage());
        }
    }


    /**
     * 根据物料分类类别查询树结构列表
     *
     * @param mtClass 物料分类类别
     * @return
     */
    @GetMapping("/findTreeByMtClass/{mtClass}")
    @ApiOperation("根据物料分类类别查询树结构列表")
    @ApiImplicitParam(name = "mtClass", value = "物料分类类别", dataType = "String")
    public R findTreeByMtClass(@PathVariable String mtClass) {
        try {
            //根据物料类别和账套查询物料分类集合
            return R.ok(BeanConverter.copyList(materielTypeService.list(Wrappers.<MaterielType>lambdaQuery()
                            .eq(MaterielType::getMtClass, mtClass)
                            .eq(BaseEntityPlus::getSetSid, SecurityUtils.getUser().getTenantId()))
                    , MaterielTypeVO.class));
        } catch (Exception e) {
            e.printStackTrace();
            return R.failed(e.getMessage());
        }
    }

    /**
     * 根据物料分类id查询允许添加的对象
     *
     * @param mtId 物料分类id
     * @return
     */
    @GetMapping("/findAllowsAddByMtId/{mtId}")
    @ApiOperation("根据物料分类id查询允许添加的对象")
    @ApiImplicitParam(name = "mtId", value = "物料分类id", dataType = "String")
    public R findAllowsAddByMtId(@PathVariable String mtId) {
        try {
            return materielTypeService.findAllowsAddByMtId(mtId);
        } catch (Exception e) {
            e.printStackTrace();
            return R.failed(e.getMessage());
        }
    }
}
